package org.ChrisRiffle.Acme.BoundingBox.workers;

import java.awt.geom.Point2D;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;

import javax.swing.JOptionPane;
import javax.swing.SwingWorker;

import org.ChrisRiffle.Acme.BoundingBox.controlers.AudioController;
import org.ChrisRiffle.Acme.BoundingBox.controlers.DataSetController;
import org.ChrisRiffle.Acme.BoundingBox.controlers.QueryDialogController;
import org.ChrisRiffle.Acme.BoundingBox.controlers.QueryPanelControler;
import org.ChrisRiffle.Acme.BoundingBox.model.DataPoint;


/**
 * Handles executing a query on a background 
 * worker thread and displaying a 'loading' panel
 * to the user while it's working
 * 
 * @author RIF
 *
 */
public class QueryExecutorWorker extends SwingWorker<List<DataPoint>,Void> {

	private static final String RESULTS_FILENAME = "query_results.txt";
	
	private File fileToSaveResults;
	
	
	@Override
	protected List<DataPoint> doInBackground() throws Exception {
		
		float lX = QueryPanelControler.INSTANCE.getLX();
		float rX = QueryPanelControler.INSTANCE.getRX();
		float uY = QueryPanelControler.INSTANCE.getUY();
		float lY = QueryPanelControler.INSTANCE.getLY();
		
		Point2D.Float topLeftCorner = 	new Point2D.Float(lX,uY);
		
		Point2D.Float bottomRightCorner = 	new Point2D.Float(rX,lY);
		
		// expensive $$
		return DataSetController.INSTANCE.queryPoints(topLeftCorner, 
				bottomRightCorner);
		
	}
	
	
	
	
	@Override
	protected void done() {
		
		//get off the 'loading' screen, go back to the 'ready' screen
		QueryDialogController.INSTANCE.displayPanelType(QueryDialogController.PANEL_TYPE.READY);
			
		int queryResultPointCount = 0;
		
		List<DataPoint> pointList = null;
		
		
		try {
			
			pointList = get();
			
			queryResultPointCount = pointList == null ? 0 : pointList.size();
			
		} catch (InterruptedException e) {			
			e.printStackTrace();			
		} catch (ExecutionException e) {			
			e.printStackTrace();
		}
		
		
		
		if(queryResultPointCount == 0){
			
			JOptionPane.showMessageDialog(null, "No points retrieved");
			return;
		}
		
				
		try {
			
			DataSetController.INSTANCE.writePointsToCsvFile(pointList, getOutputFile());
			
			// play a fun sound for a cool effect to alert of the success
			AudioController.INSTANCE.playMarioSoundInNewThread();
			
			JOptionPane.showMessageDialog(QueryDialogController.INSTANCE.getBoxDialog(), 
					queryResultPointCount + " results written to " + getOutputFile().getAbsolutePath());
			
		} catch (Exception e) {
			
			e.printStackTrace();
			JOptionPane.showMessageDialog(null, "Unable to save points to file");
			return;
		}
		
		
	}
	
	
	
	/**
	 * Gets a file reference at the jvm system user dir property,
	 * for savign the processed results
	 * 
	 * @return
	 * 		FileToSaveCsvOutput
	 * @throws IOException 
	 */
	private File getOutputFile() throws IOException {

		if (fileToSaveResults == null) {

			String userDirPath = System.getProperty("user.dir");

			fileToSaveResults = new File(userDirPath + "/" + RESULTS_FILENAME);						
			
			//start from a clean new file
			if(!fileToSaveResults.exists()){
				
				fileToSaveResults.createNewFile();
				
			}else{
				
				fileToSaveResults.delete();
				fileToSaveResults.createNewFile();
			}
			
		}
		return fileToSaveResults;
	}

}

